package com.jiyun.service.impl;
import com.alibaba.dubbo.config.annotation.Service;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.jiyun.dao.CategoryMapper;
import com.jiyun.entity.PageResult;
import com.jiyun.pojo.goods.Category;
import com.jiyun.service.goods.CategoryService;
import com.jiyun.utils.CacheKey;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import tk.mybatis.mapper.entity.Example;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class CategoryServiceImpl implements CategoryService {

    @Autowired
    private CategoryMapper categoryMapper;

    @Autowired
    RedisTemplate redisTemplate;

    /**
     * 返回全部记录
     * @return
     */
    public List<Category> findAll() {
        return categoryMapper.selectAll();
    }

    /**
     * 分页查询
     * @param page 页码
     * @param size 每页记录数
     * @return 分页结果
     */
    public PageResult<Category> findPage(int page, int size) {
        PageHelper.startPage(page,size);
        Page<Category> categorys = (Page<Category>) categoryMapper.selectAll();
        return new PageResult<Category>(categorys.getTotal(),categorys.getResult());
    }

    /**
     * 条件查询
     * @param searchMap 查询条件
     * @return
     */
    public List<Category> findList(Map<String, Object> searchMap) {
        Example example = createExample(searchMap);
        return categoryMapper.selectByExample(example);
    }

    /**
     * 分页+条件查询
     * @param searchMap
     * @param page
     * @param size
     * @return
     */
    public PageResult<Category> findPage(Map<String, Object> searchMap, int page, int size) {
        PageHelper.startPage(page,size);
        Example example = createExample(searchMap);
        Page<Category> categorys = (Page<Category>) categoryMapper.selectByExample(example);
        return new PageResult<Category>(categorys.getTotal(),categorys.getResult());
    }

    /**
     * 根据Id查询
     * @param id
     * @return
     */
    public Category findById(Integer id) {
        return categoryMapper.selectByPrimaryKey(id);
    }

    /**
     * 新增
     * @param category
     */
    public void add(Category category) {
        categoryMapper.insert(category);
        saveCategoryTreeToRedis();
    }

    /**
     * 修改
     * @param category
     */
    public void update(Category category) {
        categoryMapper.updateByPrimaryKeySelective(category);
        saveCategoryTreeToRedis();
    }

    /**
     *  删除
     * @param id
     */
    public void delete(Integer id) {
        // 查询当前的分类对象，是否被使用
        Example example = new Example(Category.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("parentId",id);
        // select count(*) from categroy where parentId = id
        int count = categoryMapper.selectCountByExample(example);
        if(count>0){
            throw new RuntimeException("存在下级分类，无法被删除！");
        }

        categoryMapper.deleteByPrimaryKey(id);
        saveCategoryTreeToRedis();
    }

    @Override
    public List<Map> findCategoryTree() {
        return (List<Map>) redisTemplate.boundValueOps(CacheKey.CATEGORY_TREE).get();
    }


    public List<Map> findCategoryTreeSQL() {
        // 1、、先去redis中查询，如果有了则直接返回数据

        // 2、、如果redis中没有，则去数据库中查询
        // 1.先查一级菜单
        Example example = new Example(Category.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("parentId",0);
        List<Category> categories = categoryMapper.selectByExample(example);

        // 将一级菜单的名字，放入到指定的集合中
        List<Map> list = new ArrayList<>();
        for (Category category : categories) {
            String name = category.getName();
            Map map = new HashMap();
            map.put("name",name);

            // 2.将一级的id，用作parentId去查询
            Integer id = category.getId();
            Example e2 = new Example(Category.class);
            Example.Criteria c2 = e2.createCriteria();
            c2.andEqualTo("parentId",id);
            List<Category> list2 = categoryMapper.selectByExample(e2);
            List<Map> l2 = new ArrayList<>();
            for (Category category2 : list2) {
                String name2 = category2.getName();
                Map map2 = new HashMap();
                map2.put("name",name2);

                // 3.使用二级的id，查询三级菜单
                Integer id2 = category2.getId();
                Example e3 = new Example(Category.class);
                Example.Criteria c3 = e3.createCriteria();
                c3.andEqualTo("parentId",id2);
                List<Category> categories3 = categoryMapper.selectByExample(e3);
                List<Map> l3 = new ArrayList<>();
                for (Category category3 : categories3) {
                    String name3 = category3.getName();
                    Map map3 = new HashMap();
                    map3.put("name",name3);
                    l3.add(map3);

                }
                map2.put("menus",l3);
                l2.add(map2);
            }

            map.put("menus",l2);
            list.add(map);
        }



        return list;
    }

    @Override
    // 缓存预热的方式，提前执行，项目启动的时候就执行
    public void saveCategoryTreeToRedis() {
        // 将数据存储到redis中
        List<Map> categoryTree = findCategoryTreeSQL();
        redisTemplate.boundValueOps(CacheKey.CATEGORY_TREE).set(categoryTree);
    }

    /**
     * 构建查询条件
     * @param searchMap
     * @return
     */
    private Example createExample(Map<String, Object> searchMap){
        Example example=new Example(Category.class);
        Example.Criteria criteria = example.createCriteria();
        if(searchMap!=null){
            // 分类名称
            if(searchMap.get("name")!=null && !"".equals(searchMap.get("name"))){
                criteria.andLike("name","%"+searchMap.get("name")+"%");
            }
            // 是否显示
            if(searchMap.get("isShow")!=null && !"".equals(searchMap.get("isShow"))){
                criteria.andLike("isShow","%"+searchMap.get("isShow")+"%");
            }
            // 是否导航
            if(searchMap.get("isMenu")!=null && !"".equals(searchMap.get("isMenu"))){
                criteria.andLike("isMenu","%"+searchMap.get("isMenu")+"%");
            }

            // 分类ID
            if(searchMap.get("id")!=null ){
                criteria.andEqualTo("id",searchMap.get("id"));
            }
            // 商品数量
            if(searchMap.get("goodsNum")!=null ){
                criteria.andEqualTo("goodsNum",searchMap.get("goodsNum"));
            }
            // 排序
            if(searchMap.get("seq")!=null ){
                criteria.andEqualTo("seq",searchMap.get("seq"));
            }
            // 上级ID
            if(searchMap.get("parentId")!=null ){
                criteria.andEqualTo("parentId",searchMap.get("parentId"));
            }
            // 模板ID
            if(searchMap.get("templateId")!=null ){
                criteria.andEqualTo("templateId",searchMap.get("templateId"));
            }

        }
        return example;
    }

}
